package io.renren.modules.question.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.renren.common.utils.IdDto;
import io.renren.common.utils.PageInput;
import io.renren.common.utils.PageUtils;
import io.renren.modules.answer.entity.Answer;
import io.renren.modules.answer.mapper.AnswerMapper;
import io.renren.modules.question.dto.input.*;
import io.renren.modules.question.dto.output.QuestionOutput;
import io.renren.modules.question.entity.QuestionMessage;
import io.renren.modules.question.entity.QuestionOption;
import io.renren.modules.question.entity.QuestionTopic;
import io.renren.modules.question.mapper.QuestionMessageMapper;
import io.renren.modules.question.mapper.QuestionOptionMapper;
import io.renren.modules.question.mapper.QuestionTopicMapper;
import io.renren.modules.question.service.QuestionService;
import io.renren.modules.score.dao.ScoreDao;
import io.renren.modules.score.entity.ScoreEntity;
import io.renren.modules.sys.entity.SysUserEntity;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author liangbaigao
 * @Date 2022/10/6 19:11
 */
@Service
public class QuestionServiceImpl implements QuestionService {

    @Resource
    private QuestionMessageMapper questionMessageMapper;
    @Resource
    private QuestionTopicMapper questionTopicMapper;
    @Resource
    private QuestionOptionMapper questionOptionMapper;
    @Resource
    private AnswerMapper answerMapper;
    @Resource
    private ScoreDao scoreDao;

    /**
     * 新增问卷
     * @param questionInput
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addQuestion(QuestionInput questionInput) {
        // 问卷对象
        QuestionMessage questionMessage = new QuestionMessage();
        questionMessage.setQuestionName(questionInput.
                getQuestionMessage().getQuestionName());
        // 默认未发布问卷
        questionMessage.setState(0);
        // 设置问卷创建人
        SysUserEntity principal = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
        questionMessage.setCreateUser(principal.getUserId());
        // 问卷入库
        questionMessageMapper.insert(questionMessage);

        // 问卷题目入库
        List<Topic> questionTopics = questionInput.getQuestionTopics();
        for (Topic topic : questionTopics) {
            QuestionTopic questionTopic = new QuestionTopic();
            // 题目名称
            questionTopic.setTopicName(topic.getTopicName());
            // 题目序号
            questionTopic.setTopicNumber(topic.getTopicNumber());
            // 是否需要上传pdf
            questionTopic.setIsPdf(topic.getIsPdf());
            // 问卷id
            questionTopic.setQuestionId(questionMessage.getId());
            questionTopicMapper.insert(questionTopic);
            // 问卷题目选项内容入库
            List<Option> questionOptionLists = topic.getQuestionOptionLists();
            questionOptionLists.forEach(option ->{
                QuestionOption questionOption = new QuestionOption();
                // 选项字母
                questionOption.setOptionAlphabet(option.getOptionAlphabet());
                // 选项分数
                questionOption.setOptionScore(option.getOptionScore());
                // 选项内容
                questionOption.setOptionName(option.getOptionName());
                // 题目id
                questionOption.setTopicId(questionTopic.getId());
                // 选项入库
                questionOptionMapper.insert(questionOption);
            });
        }
    }

    /**
     * 查看问卷名分页
     * @return
     */
    @Override
    public PageUtils showQuestion(PageInput pageInput) {
        Page<QuestionMessage> page =
                new Page<>(pageInput.getCurrPage(),pageInput.getPageSize());
        // 存放问卷数据
        List<Message> MessageList = new ArrayList<>();
        // 查询
        SysUserEntity principal = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
        Page<QuestionMessage>  questionMessageList;
        // 当为管理员时
        if(principal.getUserId().equals(1L)) {
            questionMessageList = questionMessageMapper.
                    selectPage(page, new QueryWrapper<QuestionMessage>());
        }else {
            questionMessageList = questionMessageMapper.
                    selectPage(page,new QueryWrapper<QuestionMessage>().lambda().
                            eq(QuestionMessage::getCreateUser,principal.getUserId()));
        }
        // 数据转换
        questionMessageList.getRecords().forEach(message ->{
            Message msg = new Message();
            msg.setId(message.getId());
            msg.setState(message.getState());
            msg.setQuestionName(message.getQuestionName());
            MessageList.add(msg);
        });
        // 返回 分页数据
        return new PageUtils(MessageList,(int)questionMessageList.getTotal(),
                (int)questionMessageList.getSize(),(int)questionMessageList.getCurrent());
    }

    /**
     * 根据问卷id查看问卷详情
     * @param id
     * @return
     */
    @Override
    public QuestionOutput questionDetail(IdDto id) {
        // 出参对象
        QuestionOutput questionOutput = new QuestionOutput();
        // 查询问卷
        QuestionMessage questionMessage = questionMessageMapper.selectById(id.getId());
        // 问卷id
        questionOutput.getQuestionMessage().setId(questionMessage.getId());
        // 问卷状态
        questionOutput.getQuestionMessage().setState(questionMessage.getState());
        // 问卷 名称
        questionOutput.getQuestionMessage().setQuestionName(questionMessage.getQuestionName());
        // 根据问卷id查询问卷题目
        QueryWrapper<QuestionTopic> questionTopicQueryWrapper = new QueryWrapper<>();
        questionTopicQueryWrapper.lambda().eq(QuestionTopic::getQuestionId,questionMessage.getId());
        List<QuestionTopic> questionTopics = questionTopicMapper.selectList(questionTopicQueryWrapper);
        List<Topic> topics = new ArrayList<>();
        for (QuestionTopic questionTopic : questionTopics) {
            Topic topic = new Topic();
            // 问卷id
            topic.setQuestionId(questionTopic.getQuestionId());
            // 题目id
            topic.setId(questionTopic.getId());
            // 是否需要上传pdf文件
            topic.setIsPdf(questionTopic.getIsPdf());
            // 题目序号
            topic.setTopicNumber(questionTopic.getTopicNumber());
            // 题目名称
            topic.setTopicName(questionTopic.getTopicName());
            List<Option> options = new ArrayList<>();
            // 根据题目id查询选项
            QueryWrapper<QuestionOption> questionOptionQueryWrapper = new QueryWrapper<>();
            questionOptionQueryWrapper.lambda().eq(QuestionOption::getTopicId,questionTopic.getId());
            List<QuestionOption> questionOptions = questionOptionMapper.selectList(questionOptionQueryWrapper);
            for (QuestionOption questionOption : questionOptions) {
                Option option = new Option();
                // 选项内容
                option.setOptionName(questionOption.getOptionName());
                // 选项字母
                option.setOptionAlphabet(questionOption.getOptionAlphabet());
                // 选项id
                option.setId(questionOption.getId());
                // 选项分数
                option.setOptionScore(questionOption.getOptionScore());
                // 题目id
                option.setTopicId(topic.getId());
                // 添加到题目中
                options.add(option);
                topic.setQuestionOptionLists(options);
            }
            // 添加进集合
            topics.add(topic);
        }
        // 添加题目
        questionOutput.setQuestionTopics(topics);
        return questionOutput;
    }

    /**
     * 发布问卷
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void publishQuestion(IdDto id) {
        // 校验问卷是否存在
        QuestionMessage questionMessage = questionMessageMapper.selectById(id.getId());
        if (ObjectUtil.isNull(questionMessage)){
            throw new RuntimeException("问卷不存在，请刷新后在尝试!");
        }
        // 存在则更新问卷状态
        questionMessage.setState(1);
        questionMessageMapper.updateById(questionMessage);
    }

    /**
     * 删除问卷
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteQuestion(IdDto id) {
        // 校验问卷是否存在
        QuestionMessage questionMessage = questionMessageMapper.selectById(id.getId());
        if (ObjectUtil.isNull(questionMessage)){
            throw new RuntimeException("问卷不存在，请刷新后在尝试!");
        }
        // 存在则删除问卷
        questionMessageMapper.deleteById(id.getId());
        // 删除题目
        QueryWrapper<QuestionTopic> questionTopicQueryWrapper =
                new QueryWrapper<>();
        questionTopicQueryWrapper.lambda().eq(QuestionTopic::getQuestionId,id.getId());
        List<QuestionTopic> questionTopics =
                questionTopicMapper.selectList(questionTopicQueryWrapper);
        questionTopicMapper.delete(questionTopicQueryWrapper);
        // 删除选项
        QueryWrapper<QuestionOption> questionOptionQueryWrapper =
                new QueryWrapper<>();
        for (QuestionTopic questionTopic : questionTopics) {
            questionOptionQueryWrapper.clear();
            questionOptionQueryWrapper.lambda().
                    eq(QuestionOption::getTopicId,questionTopic.getId());
            questionOptionMapper.delete(questionOptionQueryWrapper);
        }
        // 删除答卷信息
        QueryWrapper<Answer> answerQueryWrapper =
                new QueryWrapper<>();
        answerQueryWrapper.lambda().eq(Answer::getQuestionId,id.getId());
        List<Answer> answers = answerMapper.selectList(answerQueryWrapper);
        if(answers.size() != 0){
            answerMapper.delete(answerQueryWrapper);
        }
        QueryWrapper<ScoreEntity> scoreEntityQueryWrapper =
                new QueryWrapper<>();
        scoreEntityQueryWrapper.lambda().eq(ScoreEntity::getQuestionId,id.getId());
        List<ScoreEntity> scoreEntities = scoreDao.selectList(scoreEntityQueryWrapper);
        if(scoreEntities.size() != 0){
            scoreDao.delete(scoreEntityQueryWrapper);
        }
    }

    /**
     * 更改问卷信息
     * @param input
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateQuestion(UpdateQuestionInput input) {

        // 1 改问卷信息
        if(input.getNumber().equals(1)){
            // 查看问卷是否存在
            QuestionMessage questionMessage = questionMessageMapper.selectById(
                    input.getQuestionMessage().getId());
            if(ObjectUtil.isNull(questionMessage)){
                throw new RuntimeException("问卷不存在，请刷新后在尝试!");
            }
            if(questionMessage.getState().equals(1)){
                throw new RuntimeException("更改失败，问卷已发布");
            }
            questionMessage.setQuestionName(
                    input.getQuestionMessage().getQuestionName());
            questionMessageMapper.updateById(questionMessage);
        }
        // 2 改题目信息
        if(input.getNumber().equals(2)){
            // 查看问卷是否存在
            QuestionMessage questionMessage = questionMessageMapper.selectById(
                    input.getTopic().getQuestionId());
            if(ObjectUtil.isNull(questionMessage)){
                throw new RuntimeException("问卷不存在，请刷新后在尝试!");
            }
            if(questionMessage.getState().equals(1)){
                throw new RuntimeException("更改失败，问卷已发布");
            }
            QuestionTopic questionTopic = new QuestionTopic();
            questionTopic.setIsPdf(input.getTopic().getIsPdf());
            questionTopic.setId(input.getTopic().getId());
            questionTopic.setTopicName(input.getTopic().getTopicName());
            questionTopicMapper.updateById(questionTopic);
        }
        // 3 改选项信息
        if(input.getNumber().equals(3)){
            // 查看问卷是否存在
            QuestionMessage questionMessage = questionMessageMapper.selectById(
                    input.getOption().getQuestionId());
            if(ObjectUtil.isNull(questionMessage)){
                throw new RuntimeException("问卷不存在，请刷新后在尝试!");
            }
            if(questionMessage.getState().equals(1)){
                throw new RuntimeException("更改失败，问卷已发布");
            }
            QuestionOption questionOption = new QuestionOption();
            questionOption.setId(input.getOption().getId());
            questionOption.setOptionScore(input.getOption().getOptionScore());
            questionOption.setOptionName(input.getOption().getOptionName());
            questionOptionMapper.updateById(questionOption);
        }
    }
}
